package cn.schoolwow.quickflow.util;

import cn.schoolwow.quickflow.domain.FlowConfig;
import cn.schoolwow.quickflow.domain.FlowDataFeature;
import cn.schoolwow.quickflow.domain.FlowExecutorConfig;
import cn.schoolwow.quickflow.dto.FlowContextDataRange;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.quickflow.flow.CompositeBusinessFlow;
import cn.schoolwow.quickflow.flow.HasFlowConfig;
import cn.schoolwow.quickflow.listener.LoadFlowConfig;
import com.alibaba.fastjson.JSONObject;

public class QuickFlowConfigUtil {
    public static void handleHasFlowConfig(BusinessFlow businessFlow, FlowExecutorConfig flowExecutorConfig){
        if(!(businessFlow instanceof HasFlowConfig)){
            return;
        }
        HasFlowConfig hasFlowConfig = (HasFlowConfig) businessFlow;
        setFlowConfigData(businessFlow.name(), hasFlowConfig, flowExecutorConfig);
    }

    public static void handleHasFlowConfig(CompositeBusinessFlow compositeBusinessFlow, FlowExecutorConfig flowExecutorConfig){
        if(!(compositeBusinessFlow instanceof HasFlowConfig)){
            return;
        }
        HasFlowConfig hasFlowConfig = (HasFlowConfig) compositeBusinessFlow;
        setFlowConfigData(compositeBusinessFlow.name(), hasFlowConfig, flowExecutorConfig);
    }

    public static void handleLoadFlowConfig(BusinessFlow businessFlow, FlowExecutorConfig flowExecutorConfig){
        if(!(businessFlow instanceof LoadFlowConfig)){
            return;
        }
        LoadFlowConfig loadFlowConfig = (LoadFlowConfig) businessFlow;
        handleLoadFlowConfig(loadFlowConfig, flowExecutorConfig);
    }
    public static void handleLoadFlowConfig(CompositeBusinessFlow compositeBusinessFlow, FlowExecutorConfig flowExecutorConfig){
        if(!(compositeBusinessFlow instanceof LoadFlowConfig)){
            return;
        }
        LoadFlowConfig loadFlowConfig = (LoadFlowConfig) compositeBusinessFlow;
        handleLoadFlowConfig(loadFlowConfig, flowExecutorConfig);
    }

    /**根据流程名称加载配置数据*/
    public static void loadFlowConfigByName(String name, FlowExecutorConfig flowExecutorConfig){
        FlowConfig flowConfig = flowExecutorConfig.flowExecutorRootConfig.flowConfig;

        if(flowConfig.flowConfigDataContext.flowConfigDataMap.containsKey(name)){
            JSONObject requestData = flowConfig.flowConfigDataContext.flowConfigDataMap.get(name);
            for(String key:requestData.keySet()){
                Object value = requestData.get(key);
                flowExecutorConfig.flowContext.putFlowContextData(key, value, FlowContextDataRange.Flow, FlowDataFeature.FlowConfigData);
            }
        }
    }

    private static void setFlowConfigData(String flowName, HasFlowConfig hasFlowConfig, FlowExecutorConfig flowExecutorConfig){
        FlowConfig flowConfig = flowExecutorConfig.flowExecutorRootConfig.flowConfig;
        JSONObject requestData = new JSONObject();
        if(flowConfig.flowConfigDataContext.flowConfigDataMap.containsKey(flowName)){
            requestData.putAll(flowConfig.flowConfigDataContext.flowConfigDataMap.get(flowName));
        }else{
            hasFlowConfig.setRequestData(requestData);
            flowConfig.flowConfigDataContext.flowConfigDataMap.put(flowName, requestData);
            if(null!=flowConfig.flowConfigHandlerContext.flowConfigRequestDataHandler){
                try {
                    flowConfig.flowConfigHandlerContext.flowConfigRequestDataHandler.saveFlowConfigRequestData(hasFlowConfig.flowConfigCategoryName(), flowName, requestData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        for(String key:requestData.keySet()){
            Object value = requestData.get(key);
            flowExecutorConfig.flowContext.putFlowContextData(key, value, FlowContextDataRange.Flow, FlowDataFeature.FlowConfigData);
        }
    }

    private static void handleLoadFlowConfig(LoadFlowConfig loadFlowConfig, FlowExecutorConfig flowExecutorConfig){
        HasFlowConfig[] hasFlowConfigArray = loadFlowConfig.getHasFlowConfigArray();
        for(HasFlowConfig hasFlowConfig:hasFlowConfigArray){
            if(hasFlowConfig instanceof CompositeBusinessFlow){
                CompositeBusinessFlow compositeBusinessFlow = (CompositeBusinessFlow) hasFlowConfig;
                String name = compositeBusinessFlow.name();
                loadFlowConfigByName(name, flowExecutorConfig);
            }
            if(hasFlowConfig instanceof BusinessFlow){
                BusinessFlow flowConfigBusinessFlow = (BusinessFlow) hasFlowConfig;
                String name = flowConfigBusinessFlow.name();
                loadFlowConfigByName(name, flowExecutorConfig);
            }
        }
    }

}
